<?php
namespace peter\util\pagination;
/**
 * Class Pagination
 * 作者 陈浩南
 * 作用 它可以算出一个页码需要的数据，固定页码按钮数量，动态计算显示的最小页码和最大页码，给用户带来更好的体验
 * 更新时间 2017/5/27
 */
class Pagination {
    // 页码信息
    public $prePage;   // 上一页
    public $prePageHtml;
    public $nextPage;  // 下一页
    public $nextPageHtml;
    public $totalPage;   // 返回一共页码数
    public $curPage;   // 返回目前页码
    public $showNums; // 返回需要显示的页码，例如: [1,2,3,4,5]
    public $showPages;     // 返回<a href="###">1</a>
    public $showMinPage;   // 返回需要显示的最小的页码
    public $showMaxPage;   // 返回需要显示的最大的页码


    // 数据库信息
    public $startRow;  // 本页开始项
    public $numRow;    // 本页输出内容


    /**
     * Pagination constructor.
     * @param $curPage      int 目前页
     * @param $totalRows    int 数据表的总共行数
     * @param $pageRows     int 一页显示多少行数据
     * @param $url          string 页码的url，###将会自动替换成对应的页码
     * @param $showPageNum  int 显示页码的数量
     */
    public function __construct($curPage,$totalRows,$pageRows,$url = '###',$showPageNum = 5) {
        if($curPage == '' || $curPage == null) {
            $curPage = 1;
        }
        // 初始化数据库信息
        $this->startRow = ($curPage - 1) * $pageRows;
        $this->numRow = $pageRows;


        // 最大页数
        $maxPage = ceil($totalRows / $pageRows);

        // 上一页
        $pre = $curPage - 1;
        if($pre > 0) {
            $this->prePage = $pre;
        }else {
            $this->prePage = null;
        }

        // 下一页
        $next = $curPage + 1;
        if($next > $maxPage) {
            $this->nextPage = null;
        }else {
            $this->nextPage = $next;
        }


        // 计算页数按钮
        // 算出curPage左右两边的页数按钮的数量
        if($showPageNum % 2) {
            // 奇数
            $left = $right = $showPageNum / 2;
        }else {
            //偶数
            $left = floor($showPageNum / 2);
            $right = ceil($showPageNum / 2);
        }

        // 算出curPage左边的页数按钮是否缺少，缺少的添加到右边
        // $leftPage 为此次页码的最小页码
        // $rightPage 为此次页码的最大页码
        $addRight = -($curPage - $left);    // 如果$addRight > 0 则需要附加右边的按钮
        if($addRight) {
            // 因为右边需要附加，所以leftPage肯定等于0
            $leftPage = 1;
            $right += $addRight;
        }else {
            $leftPage = $curPage - $left;
        }

        // 看看右边的页码按钮是否溢出
        if($right + $curPage > $maxPage) {
            $rightPage = $maxPage;
        } else {
            $rightPage = $curPage + $right;
        }

        // 生成一个页码数组
        $this->showNums = array();
        $this->showPages = array();
        for ($i = $leftPage ; $i <= $rightPage ; ++$i) {
            array_push($this->showNums,$i);
            if($i == $curPage) {
                $html = "<li class='active'><a href='{$url}'>{$i}</a></li>";
            }else {
                $html = "<li><a href='{$url}'>{$i}</a></li>";
            }
            array_push($this->showPages,str_replace("###",$i,$html));
        }

        // 目前页码
        $this->curPage = $curPage;
        // 最大页码
        $this->totalPage = $maxPage;
        // 需要显示的最小的页码
        $this->showMinPage = isset($this->showNums[0])?$this->showNums[0]:0;
        // 需要显示的最大的页码
        $this->showMaxPage = isset($this->showNums[count($this->showNums) - 1])?$this->showNums[count($this->showNums) - 1]:0;


        $this->nextPageHtml = $this->prePageHtml = '';
        if($this->prePage) {
            $this->prePageHtml = str_replace("###",$this->prePage,"<li><a href='{$url}'>&laquo;</a></li>");
        }

        if($this->nextPage){
            $this->nextPageHtml = str_replace("###",$this->nextPage,"<li><a href='{$url}'>&raquo;</a></li>");
        }
    }

    /**
     * @return null
     */
    public function getPrePage()
    {
        return $this->prePage;
    }

    /**
     * @return 目前页
     */
    public function getNextPage()
    {
        return $this->nextPage;
    }

    /**
     * @return float
     */
    public function getTotalPage()
    {
        return $this->totalPage;
    }

    /**
     * @return 目前页
     */
    public function getCurPage()
    {
        return $this->curPage;
    }

    /**
     * @return array
     */
    public function getShowNums()
    {
        return $this->showNums;
    }

    /**
     * @return mixed
     */
    public function getShowMinPage()
    {
        return $this->showMinPage;
    }

    /**
     * @return mixed
     */
    public function getShowMaxPage()
    {
        return $this->showMaxPage;
    }

    /**
     * @return 目前页
     */
    public function getStartRow()
    {
        return $this->startRow;
    }

    /**
     * @return 一页显示多少行数据
     */
    public function getNumRow()
    {
        return $this->numRow;
    }
}
